﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class EnemyBaseMovable : EnemyBaseFixed, Person
{
    [Header("基础配置")]
    [Tooltip("移动速度：(30像素/30帧)*60帧率/16像素每单位=3.75")]
    public float speed = 3.75f;
    [Tooltip("跳起速度")]
    public float jumpSpeed = 7.0f;

    [Header("碰撞配置")]
    [Tooltip("跳台层")]

    protected Collider2D colliderGround;


    [Tooltip("状态机")]
    private readonly StateMachine<EnumState> stateMachine = new();

    [Tooltip("是否在地面")]
    protected bool onGround;

    protected override void Init()
    {
        base.Init();
        colliderGround = transform.Find("平台检测刚体")!=null?transform.Find("平台检测刚体").GetComponent<Collider2D>():null;
        boomPrefab=Constant.Prefabs.EnemyBoom2.Load();
        
    }


    protected override void PreUpdateAction(EnumState inState)
    {
        if(rig!=null){
            rig.velocity = new(lookAt.x * speed, rig.velocity.y);
        }
    }

    protected virtual bool CheckGround(){
        if(colliderGround!=null){
            return Utility.CheckGround(colliderGround, groundLayer);
        }else{
            return false;
        }
    }
    protected override void CommonFixedUpdate()
    {
        if (running)
        {
            onGround = CheckGround();
            base.CommonFixedUpdate();
        }
    }


    // public override void Run()
    // {
    //     if (!running)
    //     {
    //         base.Run();

    //         Player player = null;
    //         Player[] players = GameObject.FindObjectsOfType<Player>().Filter((Player player) =>
    //         {
    //             return player.gameObject.activeInHierarchy && player.GetLife() > 0;
    //         }).ToArray();
    //         if (players.Length > 0)
    //         {
    //             player = players[Random.Range(0, players.Length)];
    //         }

    //         float dirX;
    //         if (player != null)
    //         {
    //             dirX = player.transform.position.x - transform.position.x;
    //         }
    //         else
    //         {
    //             dirX = Camera.main.transform.position.x - transform.position.x;
    //         }
    //         lookAt = dirX >= 0 ? Vector2.right : Vector2.left;

    //     }
    // }

    protected virtual void UpdateStateNone(bool stateChanged, EnumState inState, out EnumState outState)
    {
        outState = EnumState.Walk;
    }
    protected virtual void UpdateStateIdle(bool stateChanged, EnumState inState, out EnumState outState)
    {
        outState = EnumState.Walk;
    }
    protected virtual void UpdateStateWalk(bool stateChanged, EnumState inState, out EnumState outState)
    {
        outState = inState;
        if (!onGround)
        {
            //行走时脚下没有地面，随机判断跳起或直接落下
            int r = Random.Range(0, 3);
            switch (r)
            {
                case 0:
                    Jump(inState, out outState);
                    break;
                case 1:
                    outState = EnumState.Fall;
                    break;
                case 2:
                    lookAt.x *= -1;
                    break;
            }
        }

        rig.velocity = new Vector2(lookAt.x * speed, rig.velocity.y);
        if (animator != null)
        {
            animator.SetInteger("state", (int)EnumState.Walk);
        }
    }
    protected virtual void UpdateStateJump(bool stateChanged, EnumState inState, out EnumState outState)
    {
        outState = inState;
        UpdateStateFall(stateChanged, inState, out outState);
        if (animator != null)
        {
            animator.SetInteger("state", (int)EnumState.Jump);
        }

    }
    protected override void UpdateStateDie(bool stateChanged, EnumState inState, out EnumState outState)
    {
        base.UpdateStateDie(stateChanged, inState, out outState);
        dieAction.Update((SeqAction seq) =>
        {
            Vector3 diePosition = transform.position;
            if (!seq.PropertyVector.TryGetValue("diePosition", out diePosition))
            {
                diePosition = transform.position;
                seq.PropertyVector.Add("diePosition", diePosition);
            }
            int i = seq.seqNo;
            if (i < dieMovePixel.Length)
            {
                Vector2 pixel = dieMovePixel[i];
                float x = pixel.x / 16;
                float y = pixel.y / 16;
                transform.position = diePosition + new Vector3(-lookAt.x * x, y, 0);
            }
            else
            {
                if (boomPrefab != null)
                {
                    Instantiate(boomPrefab, transform.position, Quaternion.identity);
                    Constant.Sounds.EnemyDeath1.PlayOneShot();
                }
                Destroy(gameObject);
            }
        });
    }
    protected virtual void UpdateStateFall(bool stateChanged, EnumState inState, out EnumState outState)
    {
        outState = inState;
        if (onGround && Mathf.Abs(rig.velocity.y) < 0.001)
        {
            outState = EnumState.Walk;
        }

        if (animator != null)
        {
            animator.SetInteger("state", (int)EnumState.Fall);
        }
    }

    protected void Jump(EnumState inState, out EnumState outState)
    {
        rig.velocity = new Vector2(rig.velocity.x, jumpSpeed);
        outState = EnumState.Jump;
    }
    public override float Damage(GameObject source, float value)
    {
        float ret = -1;
        if (running)
        {
            ret = value;
            health -= value;
            if (health <= 0)
            {
                ret = health + value;
                Die();
            }
        }
        return ret;
    }


    public void SetFootPosition(Vector2 targetFootPoint)
    {
        Vector2 footPoint = GetBodyPartPosition(Person.BodyPart.Foot);
        Vector2 point = transform.position;
        Vector2 targetPoint = point - footPoint + targetFootPoint;
        transform.position = targetPoint;
    }


    public override Vector2 GetBodyPartPosition(Person.BodyPart bodyPart)
    {
        Vector2 ret;
        switch (bodyPart)
        {
            case Person.BodyPart.Foot:
                {
                    Collider2D colliderFoot = transform.Find("平台检测刚体").GetComponent<Collider2D>();
                    Bounds bounds = colliderFoot.bounds;
                    ret = new(bounds.center.x, bounds.min.y);
                }
                break;
            default:
                throw new System.NotImplementedException();
        }
        return ret;
    }

    public override bool IsDie()
    {
        return state == EnumState.Die;
    }
}
